package com.mindbook.vip.gawxchatinfo.config;

import com.mindbook.vip.gawxchatinfo.exception.AuthCode2SessionException;
import com.mindbook.vip.gawxchatinfo.exception.BasicException;
import com.mindbook.vip.gawxchatinfo.exception.crud.CurdException;
import com.mindbook.vip.gawxchatinfo.exception.sql.SqlException;
import com.mindbook.vip.gawxchatinfo.exception.wx.AccessTokenException;
import com.mindbook.vip.gawxchatinfo.utils.result.Result;
import com.mindbook.vip.gawxchatinfo.utils.result.ResultEnum;
import com.mindbook.vip.gawxchatinfo.utils.result.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.BindingException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @NAME: wxb
 * @DATE: 2022/3/9
 * @DESCRIOPTION: 统一异常处理
 **/
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerConfig {

    /**
     * 未知异常统一处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Result exceptionHandler(Exception e){
        e.printStackTrace();
        log.error(e.getMessage());
        return ResultUtils.genErrorResult(500,"未捕获异常");
    }

    @ExceptionHandler(value= MethodArgumentNotValidException.class)
    public Result handleVaildException(MethodArgumentNotValidException e){
        log.error("数据校验出现问题{}，异常类型：{}",e.getMessage(),e.getClass());
        BindingResult bindingResult = e.getBindingResult();

        return ResultUtils.genErrorResult(ResultEnum.VALIDATE_PARAMS_LOST.getCode(),e.getMessage());

    }

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public Result missingServletRequestParameterException(MissingServletRequestParameterException e){
        return ResultUtils.genErrorResult(400,e.getMessage());
    }

    @ExceptionHandler(value = CurdException.class)
    public Result missingServletRequestParameterException(CurdException e){
        ResultEnum resultEnum = e.getResultEnum();
        return ResultUtils.genErrorResult(resultEnum.getCode(),resultEnum.getMsg());
    }

    /**
     * 处理微信authCode2Session的异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthCode2SessionException.class)
    public Result AuthCode2Session(AuthCode2SessionException e){
        return ResultUtils.genErrorResult(Integer.parseInt(e.getCode()),e.getMsg());
    }

    @ExceptionHandler(value = AuthenticationException.class)
    public Result AuthenticatioinException(AuthenticationException e){
        e.printStackTrace();
        String className = e.getClass().getSimpleName();
        ResultEnum resultEnum = null;
        switch (className){
            case "CredentitalsException":
                resultEnum=ResultEnum.SHIRO_CREDENTITALS_EXCEPTION;
                break;
            case "IncorrectCredentialsException":
                resultEnum = ResultEnum.SHIRO_INCORRECT_CREDENTIALS_EXCEPTION;
                break;
            case "UnsupportedTokenException":
                resultEnum = ResultEnum.SHIRO_UNSUPPORTED_TOKEN_EXCEPTION;
                break;
            case "UnknownAccountException":
                resultEnum = ResultEnum.SHIRO_UNKNOWN_ACCOUNT_EXCEPTION;
                break;
            case "LockedAccountException":
                resultEnum = ResultEnum.SHIRO_LOCKED_ACCOUNT_EXCEPTION;
                break;
            case "DisabledAccountException":
                resultEnum = ResultEnum.SHIRO_DISABLED_ACCOUNT_EXCEOPTION;
                break;
            case "ExcessiveAttemptsException":
                resultEnum = ResultEnum.SHIRO_EXCESSIVE_ATTEMPTS_EXCEPTION;
                break;
            case "ConcurrentAccessException":
                resultEnum = ResultEnum.SHIRO_CONCURRENT_ACCESS_EXCEPTION;
                break;
            case "AccountException":
                resultEnum = ResultEnum.SHIRO_ACCOUNT_EXCEPTION;
                break;
            case "ExpiredCredentialsException":
                resultEnum = ResultEnum.SHIRO_EXPIRED_CREDENTIALS_EXCEPTION;
                break;
            case "CredentialsException":
                resultEnum = ResultEnum.SHIRO_CREDENTIALS_EXCEPTION;
                break;
            case "UnauthorizedException":
                resultEnum = ResultEnum.SHIRO_UNAUTHORIZED_EXCEPTION;
                break;
            case "UnanthenticatedException":
                resultEnum = ResultEnum.SHIRO_UNANTHENTICATED_EXCEPTION;
                break;
        }
        return ResultUtils.genErrorResult(resultEnum);
    }


    /**
     * 处理获取微信access_token的值的异常
     * @param e 自定义的access_token的值
     * @return
     */
    @ExceptionHandler(value = BasicException.class)
    public Result AccessTokenException(BasicException e){
        return ResultUtils.genErrorResult(e.getCode(),e.getMsg());
    }

    /**
     * 数据库请求异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = SQLIntegrityConstraintViolationException.class)
    public Result AccessTokenException(SQLIntegrityConstraintViolationException e){
        return ResultUtils.genErrorResult(9,e.getMessage());
    }

    /**
     * 自定义的sql操作异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = SqlException.class)
    public Result AccessTokenException(SqlException e){
        return ResultUtils.genErrorResult(e.getCode(),e.getMessage());
    }

    /**
     * 自定义的sql操作异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result AccessTokenException(HttpRequestMethodNotSupportedException e){
        return ResultUtils.genErrorResult(403,e.getMessage());
    }

}
